from django.core.exceptions        import ImproperlyConfigured
from django.db                     import models
from django.utils.encoding         import smart_unicode
from django.utils.importlib        import import_module
from django.utils.translation      import ugettext_lazy as _
from sitepal.sitebase.managers     import ResourceManager
from sitepal.sitebase.models       import Resource
from sitepal.sitetheme.exceptions  import RendererDoesNotExist
from sitepal.sitetheme.renderers   import ContainerRenderer

GRID_COUNT              = 24
GRID_MIN_WIDTH          = 1
GRID_MAX_WIDTH          = GRID_COUNT
GRID_MIN_PREFIX         = 1
GRID_MAX_PREFIX         = GRID_COUNT-1
GRID_MIN_SUFFIX         = 1
GRID_MAX_SUFFIX         = GRID_COUNT-1
GRID_MIN_WEIGHT         = -(GRID_COUNT-1)
GRID_MAX_WEIGHT         = GRID_COUNT-1
GRID_CLEAR_CHOICES      = (('none',       _("no clearing")),
                           ('before',     _("clear before")),
                           ('after',      _("clear after")),
                           ('both',       _("clear before and after")),)
GRID_POSITION_CHOICES   = (('',           _("no positioning")),
                           ('alpha',      _("head element")),
                           ('omega',      _("tail element")),
                           ('alpha omega',_("head and tail element")),)
GRID_CUSTOM_CHOICES     = (('user',       _("users can control")),
                           ('display',    _("on by default")),
                           ('hidden',     _("hidden by default")),)
GRID_VISIBILITY_CHOICES = (('exclude',    _("exclude from listed pages")),
                           ('include',    _("show only on listed pages")),
                           ('all',        _("show on all pages")),
                           ('custom',     _("use method to determine visibility")),)

class ContainerManager(ResourceManager):
    def sync_object(self,name,data):
        created,obj = super(ContainerManager,self).sync_object(name,data)
        try:
            obj.title           = data['title']
            obj.description     = data.get('description')
            obj.display_title   = data.get('display_title',True)
            obj.style           = data.get('style')
            obj.weight          = data.get('weight',0)
            obj.grid_custom     = data.get('grid_custom','display')
            obj.grid_clear      = data.get('grid_clear','none')
            obj.grid_pages      = data.get('grid_pages')
            obj.grid_position   = data.get('grid_position','')
            obj.grid_prefix     = data.get('grid_prefix',0)
            obj.grid_suffix     = data.get('grid_suffix',0)
            obj.grid_visibility = data.get('grid_visibility','all')
            obj.grid_weight     = data.get('grid_weight',0)
            obj.grid_width      = data['grid_width']
            if created:
                obj.grid_enabled = obj.grid_custom in ('user','display')
            return created,obj
        except Exception,e:
            raise ImproperlyConfigured,e

class Container(Resource):
    title           = models.CharField(_("title"),editable=False,max_length=100)
    description     = models.TextField(_("description"),max_length=2048,editable=False,
                                       blank=True,null=True)
    display_title   = models.BooleanField(_("display title"),default=False)
    style           = models.CharField(_("style"),max_length=250,blank=True,null=True)
    weight          = models.IntegerField(_("weight"),default=0)
    grid_custom     = models.CharField(_("custom"),max_length=10,default='display',
                                       choices=GRID_CUSTOM_CHOICES)
    grid_clear      = models.CharField(_("grid clear"),max_length=10,default='none',
                                       choices=GRID_CLEAR_CHOICES)
    grid_enabled    = models.BooleanField(_("enabled"),default=True)
    grid_pages      = models.TextField(_("pages"),max_length=2048,blank=True,null=True)
    grid_position   = models.CharField(_("grid position"),max_length=20,default='',blank=True,
                                       choices=GRID_POSITION_CHOICES)
    grid_prefix     = models.IntegerField(_("grid prefix"),default=0)
    grid_suffix     = models.IntegerField(_("grid suffix"),default=0)
    grid_weight     = models.IntegerField(_("grid weight"),default=0)
    grid_width      = models.IntegerField(_("grid width"))
    grid_visibility = models.CharField(_("visibility"),max_length=10,default='all',
                                       choices=GRID_VISIBILITY_CHOICES)
    objects         = ContainerManager()

    class Meta(Resource.Meta):
        verbose_name        = _('container')
        verbose_name_plural = _('containers')
        unique_together     = ('site','name')
        app_label           = 'sitetheme'
        ordering            = ('grid_weight','weight','name')

    def __unicode__(self):
        return self.name

    @property
    def attributes(self):
        if not hasattr(self,'_attributes'):
            self._attributes = {
                'id'   : 'id_{0}'.format(self.name),
                'class': u' '.join(self.display_classes),
                'title': self.title
            }
            if self.style:
                self._attributes.update({'style': self.style})
        return self._attributes

    @property
    def display_classes(self):
        return (smart_unicode(self.name),u'container')

    def is_visible(self,request):
        return True

    @property
    def render_class(self):
        if hasattr(self,'_renderer_class'):
            return self._renderer_class
        if hasattr(self,'renderer_name') and self.renderer_name:
            try:
                dot            = self.renderer_name.rindex('.')
                module_name    = self.renderer_name[:dot]
                class_name     = self.renderer_name[dot+1:]
                renderer_class = getattr(import_module(module_name),class_name)
                if not issubclass(renderer_class,ContainerRenderer):
                    raise RendererDoesNotExist,"{0} is not a container renderer".format(self.renderer_name)
                self._renderer_class = renderer_class
                return renderer_class
            except (ValueError,ImportError,AttributeError):
                raise RendererDoesNotExist,"Unknown class: {0}".format(self.renderer_name)
        raise RendererDoesNotExist,"No renderer defined"

    def save(self,*args,**kwargs):
        if hasattr(self,'_attributes'):
            delattr(self,'_attributes')
        super(Container,self).save(*args,**kwargs)

